﻿using System.Reflection;
using rpc_service.cache;

namespace rpc_service.util;

public class MethodUtil
{
    // 存储接口类型到其实现实例的映射
    private static Dictionary<Type, object> _instanceCache = new Dictionary<Type, object>();
    // 存储类型名称到类型的映射
    private static Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
    // 存储代理实例
    private static Dictionary<Type, object> _proxyCache = new Dictionary<Type, object>();

    public static string InvokeMethod(string methodSignature)
    {
        try
        {
            object result = null;
            
            string[] parts = methodSignature.Split('.');
            string typeName = string.Join(".", parts, 0, parts.Length - 1);
            string methodName = parts[parts.Length - 1];
            
            // 尝试获取类型
            Type type = FindType(typeName);
            
            if (type == null)
            {
                Console.WriteLine($"警告: 类型 {typeName} 未找到");
                return string.Empty;
            }
            
            // 获取方法信息
            MethodInfo methodInfo = type.GetMethod(methodName);
            if (methodInfo == null)
            {
                Console.WriteLine($"警告: 方法 {methodName} 未找到");
                return string.Empty;
            }

            if (methodInfo.ReturnType != "string".GetTypeByStr())
            {
                Console.WriteLine($"警告: 方法 {methodInfo.Name} 必须返回字符串类型");
                return string.Empty;
            }
            
            // 检查是否为静态方法
            if (methodInfo.IsStatic)
            {
                // 静态方法直接调用，不需要实例
                result = methodInfo.Invoke(null, null);
                return result?.ToString() ?? string.Empty;
            }
            
            // 非静态方法需要实例
            object instance;
            
            // 检查是否有缓存的实例
            if (_instanceCache.TryGetValue(type, out instance))
            {
                // 使用缓存的实例
                result = methodInfo.Invoke(instance, null);
                return result?.ToString() ?? string.Empty;
            }
            
            // 检查是否为接口
            if (type.IsInterface)
            {
                // 尝试查找已注册的代理实例
                instance = GetProxyInstance(type);
                if (instance == null)
                {
                    Console.WriteLine($"警告: 无法找到接口 '{typeName}' 的代理实例，请先注册代理实例");
                    return string.Empty;
                }
            }
            else
            {
                // 尝试创建普通类的实例
                try
                {
                    instance = Activator.CreateInstance(type);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"警告: 无法创建类型 '{typeName}' 的实例: {ex.Message}");
                    return string.Empty;
                }
                
                if (instance == null)
                {
                    Console.WriteLine($"警告: 无法创建类型 '{typeName}' 的实例");
                    return string.Empty;
                }
            }
            
            // 缓存实例以供后续使用
            _instanceCache[type] = instance;
            
            // 调用方法
            result = methodInfo.Invoke(instance, null);
            return result?.ToString() ?? string.Empty;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"调用方法时出错: {ex.Message}");
            if (ex.InnerException != null)
            {
                Console.WriteLine($"内部异常: {ex.InnerException.Message}");
            }
            return string.Empty;
        }
    }
    
    public static Type FindType(string typeName, bool isExcludeInterface = true)
    {
        // 首先尝试直接获取类型
        Type type = Type.GetType(typeName);
        if (type != null && (!type.IsInterface || !isExcludeInterface))
        {
            _typeCache[typeName] = type;
            return type;
        }
        
        // 首先检查缓存
        if (_typeCache.TryGetValue(typeName, out Type cachedType))
        {
            return cachedType;
        }
        
        // 在所有已加载的程序集中查找类型
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            // 尝试在当前程序集中查找完全匹配的类型
            type = assembly.GetType(typeName);
            if (type != null && !type.IsAbstract && !type.IsInterface)
            {
                _typeCache[typeName] = type;
                return type;
            }
            
            // 检查是否为动态生成的程序集
            if (assembly.IsDynamic || assembly.GetName().Name?.StartsWith("Dynamic") == true)
            {
                // 在动态程序集中查找所有类型
                Type[] types;
                try
                {
                    types = assembly.GetTypes();
                }
                catch
                {
                    // 某些动态程序集可能无法获取类型
                    continue;
                }
                
                foreach (var t in types)
                {
                    // 检查类型名称是否匹配
                    if (t.FullName == typeName || t.Name == typeName)
                    {
                        _typeCache[typeName] = t;
                        return t;
                    }
                    
                    // 检查是否为接口的实现类
                    var interfaces = t.GetInterfaces();
                    foreach (var iface in interfaces)
                    {
                        if (iface.FullName == typeName || iface.Name == typeName)
                        {
                            _typeCache[typeName] = t;
                            return t;
                        }
                    }
                }
            }
        }
        
        // 如果找不到类型，尝试加载包含该类型的程序集
        try
        {
            string possibleAssemblyName = typeName.Split('.')[0];
            Assembly loadedAssembly = Assembly.Load(possibleAssemblyName);
            return FindType(typeName); // 递归调用，尝试在新加载的程序集中查找
        }
        catch
        {
            // 忽略加载失败的异常
        }
        
        return null;
    }
    
    // 注册类型
    public static void RegisterType(string typeName, Type type)
    {
        if (!string.IsNullOrEmpty(typeName) && type != null)
        {
            _typeCache[typeName] = type;
        }
    }
    
    // 注册代理实例
    public static void RegisterProxyInstance(Type interfaceType, object proxyInstance)
    {
        if (interfaceType != null && proxyInstance != null)
        {
            _proxyCache[interfaceType] = proxyInstance;
            _instanceCache[interfaceType] = proxyInstance;
        }
    }
    
    // 获取代理实例
    private static object GetProxyInstance(Type interfaceType)
    {
        if (_proxyCache.TryGetValue(interfaceType, out object instance))
        {
            return instance;
        }
        return null;
    }
}